package com.banciyuan.bcywebview.biz.main.newdiscover;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.banciyuan.bcywebview.R;
import com.banciyuan.bcywebview.api.NovelApi;
import com.banciyuan.bcywebview.api.TagApi;
import com.banciyuan.bcywebview.base.factory.TimelineFactory;
import com.banciyuan.bcywebview.base.fragment.BaseLazyContainerFragment;
import com.banciyuan.bcywebview.base.helper.ProgressbarHelper;
import com.banciyuan.bcywebview.base.helper.data.UserDataHelper;
import com.banciyuan.bcywebview.base.helper.push.Item.BasePush;
import com.banciyuan.bcywebview.base.helper.push.Item.PushError;
import com.banciyuan.bcywebview.base.helper.push.PushFactory;
import com.banciyuan.bcywebview.base.view.pulltorefresh.PullToRefreshBase;
import com.banciyuan.bcywebview.base.view.pulltorefresh.PullToRefreshListView;
import com.banciyuan.bcywebview.biz.circles.smooth.CircleSmoothActivity;
import com.banciyuan.bcywebview.biz.circles.smooth.CircleTagSmoothActivity;
import com.banciyuan.bcywebview.biz.main.discover.top.TopFragment;
import com.banciyuan.bcywebview.biz.main.discover.newestwork.NewestWorkActivity;
import com.banciyuan.bcywebview.biz.main.discover.topcreator.TopCreatorActivity;
import com.banciyuan.bcywebview.biz.main.discover.topwork.NovelTopWorkActivity;
import com.banciyuan.bcywebview.biz.novel.NovelAdapter;
import com.banciyuan.bcywebview.utils.http.BcyPair;
import com.banciyuan.bcywebview.utils.http.HttpUtils;
import com.banciyuan.bcywebview.utils.http.OnErrorProxy;
import com.banciyuan.bcywebview.utils.http.StatusCodeUtils;
import com.banciyuan.bcywebview.utils.http.StringRequestParam;
import com.banciyuan.bcywebview.utils.http.VolleyQueue;
import com.banciyuan.bcywebview.utils.intent.gotoUtil;
import com.banciyuan.bcywebview.utils.universalimageloader.core.ImageLoader;
import com.banciyuan.bcywebview.utils.universalimageloader.utils.ImageOptions;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import de.greenrobot.daoexample.model.DiscoverData;
import de.greenrobot.daoexample.model.HotEvent;
import de.greenrobot.daoexample.model.Novel;
import de.greenrobot.daoexample.model.TagDetail;

/**
 * Created by squall on 2016/5/25.
 */
public class NovelDiscoverFragment extends BaseLazyContainerFragment implements View.OnClickListener {

    private ProgressbarHelper mProgressbarHelper;
    private View mProgressbarView;

    private TextView rela_name;
    private TextView top_user;
    private TextView hot_item;
    private TextView newest_item;
    private ImageView list_label;

    private PullToRefreshListView mRefresh;
    private ListView mListView;
    private RequestQueue queue;
    private NovelAdapter novelAdapter;
    private List<Novel> nlist = new ArrayList<>();
    private List<Novel> dataTemp = new ArrayList<>();
    private List<String> addstatus = new ArrayList<>();
    private List<HotEvent> elist = new ArrayList<>();

    private int page = 1;
    private boolean end_flag = false;
    private boolean load_flag = false;

    private LinearLayout relateContainer;
    private View relateCircleviewLayout;
    private DiscoverData discoverData = new DiscoverData();

    private boolean eventEnd;
    private boolean dataEnd;
    private int lastPages;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.not_login_discover, null);
        initArgs();
        initProgressbar(rootView);
        initUi(rootView);
        initAction();
        return rootView;
    }

    @Override
    protected void initArgs() {
        queue = VolleyQueue.getRquest(getActivity());
    }

    @Override
    protected void initAction() {
        mRefresh.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>() {
            @Override
            public void onRefresh(PullToRefreshBase<ListView> refreshView) {
                load_flag = false;
                end_flag = false;
                eventEnd = false;
                dataEnd = false;
                lastPages = 0;
                page = 1;
                addstatus.clear();
                fetchData();
            }
        });

        mRefresh.setOnLastItemVisibleListener(new PullToRefreshBase.OnLastItemVisibleListener() {
            @Override
            public void onLastItemVisible() {
                if (!load_flag && !end_flag) {
                    page++;
                    initData();
                }
            }
        });
    }

    @Override
    protected void initProgressbar(View rootview) {
        mProgressbarView = rootview.findViewById(R.id.base_progressbar);
        mProgressbarHelper = new ProgressbarHelper(mProgressbarView);
        mProgressbarHelper.setActionCallbacks(new ProgressbarHelper.OnProgressCallbacks() {
            @Override
            public void onActionClick(int id) {
                mProgressbarHelper.onLoading();
                fetchData();
            }
        });
        mProgressbarHelper.onLoading();
    }

    @Override
    protected void initUi(View rootview) {
        mRefresh = (PullToRefreshListView) rootview.findViewById(R.id.refreshview);
        mListView = mRefresh.getRefreshableView();
        View header = View.inflate(getActivity(), R.layout.discover_mould_novel, null);
        initHeaderView(header);

        mListView.addHeaderView(header);
    }


    private void initHeaderView(View header) {
        rela_name = (TextView) header.findViewById(R.id.circle_rela_name);
        rela_name.setText(getString(R.string.circle_novel));
        list_label = (ImageView) header.findViewById(R.id.list_label);
        list_label.setImageResource(R.drawable.hot_write);
        top_user = (TextView) header.findViewById(R.id.top_100);
        top_user.setText(getString(R.string.top_novel_100));
        hot_item = (TextView) header.findViewById(R.id.list_name);
        hot_item.setText(getString(R.string.hot_write));
        newest_item = (TextView) header.findViewById(R.id.more_tv);
        newest_item.setText(getString(R.string.newest_write));
        relateCircleviewLayout = header.findViewById(R.id.circle_hot);
        relateContainer = (LinearLayout) relateCircleviewLayout.findViewById(R.id.view_container_hobbycircle);
        top_user.setOnClickListener(this);
        newest_item.setOnClickListener(this);
        header.findViewById(R.id.daily_rank).setOnClickListener(this);
        header.findViewById(R.id.week_rank).setOnClickListener(this);
        header.findViewById(R.id.feed_rank).setOnClickListener(this);
    }


    @Override
    protected void initData() {
        load_flag = true;
        String url = HttpUtils.BASE_URL + NovelApi.getHotNovel();
        List<BcyPair> pairs = new ArrayList<>();
        pairs.add(new BcyPair(HttpUtils.TOKEN, UserDataHelper.getInstance(getActivity()).getToken()));
        pairs.add(new BcyPair(HttpUtils.INDEX_P, String.valueOf(page)));
        Map<String, String> map = HttpUtils.getData(pairs);

        Response.Listener<String> onSucc = new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    if (StatusCodeUtils.dealStatusCode(response, getActivity())) {
                        JSONObject jsonObject = new JSONObject(response);
                        String result = jsonObject.getString(HttpUtils.UPLOAD_DATA);
                        Gson gson = new Gson();
                        dataTemp = gson.fromJson(result, new TypeToken<List<Novel>>() {
                        }.getType());
                        setWorkToTag(dataTemp);
                        dataEnd = true;
                        checkEnd();
                    } else {
                        dataEnd = true;
                        checkEnd(false);
                        load_flag = false;
                    }
                } catch (Exception e) {
                    dataEnd = true;
                    checkEnd(false);
                    load_flag = false;
                }
            }
        };

        Response.ErrorListener onError = new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                dataEnd = true;
                checkEnd(false);
                load_flag = false;
            }
        };

        OnErrorProxy onErrorProxy = new OnErrorProxy(onError, onSucc, url, getActivity(), map);
        StringRequestParam requestParam = new StringRequestParam(Request.Method.POST, url, map, onSucc, onErrorProxy);
        queue.add(requestParam);
    }


    private void setWorkToTag(List<Novel> templist) {
        for (Novel novel : templist) {
            if (!TextUtils.isEmpty(novel.getWork())) {
                TagDetail tagDetail = new TagDetail();
                tagDetail.setWork(novel.getWork());
                tagDetail.setWid(novel.getWid());
                tagDetail.setTag_name(novel.getWork());
                novel.getPost_tags().add(0, tagDetail);
            }
        }
    }

    private void buildMainData(List<Novel> templist, int start) {
        int size = start + templist.size();
        if (size >= 3 && elist.size() >= 2 && !addstatus.contains("event1")) {
            Novel novel = new Novel();
            novel.getEvents().addAll(elist.subList(0, 2));
            if (3 - start >= 0) {
                templist.add(3 - start, novel);
                addstatus.add("event1");
            }
        }
        if (size >= 7 && elist.size() >= 4 && !addstatus.contains("event2")) {
            Novel novel = new Novel();
            novel.getEvents().addAll(elist.subList(2, 4));
            if (3 - start >= 0) {
                templist.add(7 - start, novel);
                addstatus.add("event2");
            }
        }
        if (size >= 11 && elist.size() >= 6 && !addstatus.contains("event3")) {
            Novel novel = new Novel();
            novel.getEvents().addAll(elist.subList(4, 6));
            if (11 - start >= 0) {
                templist.add(11 - start, novel);
                addstatus.add("event3");
            }
        }
    }

    private void checkEnd() {
        checkEnd(true);
    }

    private void checkEnd(boolean succ) {
        if (eventEnd && dataEnd) {
            if (succ) {
                buildMainData(dataTemp, lastPages);
                renderData(dataTemp);
                lastPages = nlist.size();
            } else {
                load_flag = false;
                mRefresh.onRefreshComplete();
                mProgressbarHelper.onFailed();
            }
        }
    }

    @Override
    public void selfUpdateData() {
        if (null != mRefresh) {
            mRefresh.setRefreshing();
        }
    }

    private void renderData(List<Novel> templist) {
        if (page == 1) {
            nlist.clear();
        }
        if (templist.isEmpty()) {
            end_flag = true;
        }
        nlist.addAll(templist);
        if (novelAdapter != null) {
            novelAdapter.notifyDataSetChanged();
        } else {
            novelAdapter = new NovelAdapter(getActivity(), nlist);
            mListView.setAdapter(novelAdapter);
        }
        mRefresh.onRefreshComplete();
        mProgressbarHelper.onSuccess();
        load_flag = false;
    }

    @Override
    public void fetchData() {
        initData();
        getHotEvent();
        getCoreStatus();
    }

    private void getCoreStatus() {
        String url = HttpUtils.BASE_URL + TagApi.getStatus();
        List<BcyPair> paramsList = new ArrayList<>();
        paramsList.add(new BcyPair(HttpUtils.NAME, getString(R.string.write)));
        if (UserDataHelper.ifLogin(getActivity()))
            paramsList.add(new BcyPair(HttpUtils.TOKEN, UserDataHelper.getInstance(getActivity()).getToken()));
        Map<String, String> map = HttpUtils.getData(paramsList);
        Response.Listener onSucc = new Response.Listener<String>() {
            @Override
            public void onResponse(String result) {
                try {
                    if (StatusCodeUtils.dealStatusCode(result, getActivity())) {
                        JSONObject jsonObject = new JSONObject(result);
                        Gson gson = new Gson();
                        discoverData = gson.fromJson(jsonObject.getJSONObject(HttpUtils.UPLOAD_DATA).toString(), new TypeToken<DiscoverData>() {
                        }.getType());
                        TimelineFactory.popNewCircleIllegalType(discoverData.getRela());
                        renderRelaCircle(discoverData.getRela());
                    } else {
                        mProgressbarHelper.onFailed();
                    }
                } catch (Exception e) {
                    mProgressbarHelper.onFailed();
                }
            }
        };

        Response.ErrorListener onError = new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                mProgressbarHelper.onFailed();
            }
        };

        OnErrorProxy errorProxy = new OnErrorProxy(onError, onSucc, url, getActivity(), map);
        StringRequestParam getUserdataRequest = new StringRequestParam(Request.Method.POST, url, map, onSucc, errorProxy);
        queue.add(getUserdataRequest);
    }


    private void getHotEvent() {
        String url = HttpUtils.BASE_URL + NovelApi.getHotEvent();
        List<BcyPair> pairs = new ArrayList<>();
        Map<String, String> map = HttpUtils.getData(pairs);
        Response.Listener<String> onSucc = new Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                try {
                    if (StatusCodeUtils.dealStatusCode(s, getActivity())) {
                        Gson gson = new Gson();
                        JSONObject jsonObject = new JSONObject(s);
                        String result = jsonObject.getString("data");
                        elist = gson.fromJson(result, new TypeToken<List<HotEvent>>() {
                        }.getType());
                        popIllegalDiscoverEvent(elist);
                        eventEnd = true;
                        checkEnd();
                    } else {
                        eventEnd = true;
                        checkEnd();
                    }
                } catch (Exception e) {
                    eventEnd = true;
                    checkEnd();
                }
            }
        };

        Response.ErrorListener onError = new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                eventEnd = true;
                checkEnd();
            }
        };

        OnErrorProxy onErrorProxy = new OnErrorProxy(onError, onSucc, url, getActivity(), map);
        StringRequestParam requestParam = new StringRequestParam(Request.Method.POST, url, map, onSucc, onErrorProxy);
        queue.add(requestParam);
    }

    private void popIllegalDiscoverEvent(List<HotEvent> tlist) {
        List<HotEvent> illegalData = new ArrayList<>();
        for (int i = 0; i < tlist.size(); i++) {
            BasePush basePush = PushFactory.getPush(tlist.get(i).getCode());
            if (basePush instanceof PushError) {
                illegalData.add(tlist.get(i));
            }
        }
        tlist.removeAll(illegalData);
    }


    private void renderRelaCircle(List<TagDetail> tlist) {
        LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
        relateContainer.removeAllViews();
        for (int i = 0; i < tlist.size(); i++) {
            final TagDetail tagDetail = tlist.get(i);
            View itemView = layoutInflater.inflate(R.layout.categorytag_item, relateContainer, false);
            ImageView ivCategroyTagCover = (ImageView) itemView.findViewById(R.id.iv_categorytag_cover);
            TextView tvCategroyTagName = (TextView) itemView.findViewById(R.id.tv_categorytag_name);
            ImageLoader.getInstance().displayImage(tagDetail.getCover(), ivCategroyTagCover, ImageOptions.options);
            if (!TextUtils.isEmpty(tagDetail.getReal_name())) {
                tvCategroyTagName.setText(tagDetail.getReal_name());
            } else {
                tvCategroyTagName.setText(tagDetail.getTag_name());
            }
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!TextUtils.isEmpty(tagDetail.getWid())) {
                        gotoUtil.gotoAct(getActivity(), CircleSmoothActivity.class, tagDetail.getReal_name(), tagDetail.getWid());
                    } else {
                        Intent intent = new Intent(getActivity(), CircleTagSmoothActivity.class);
                        intent.putExtra("type", "tag");
                        intent.putExtra(gotoUtil.INTENT_VALUE_ONE, tagDetail.getTag_name());
                        startActivity(intent);
                    }
                }
            });
            relateContainer.addView(itemView);
        }
    }

    @Override
    public void onClick(View v) {
        Intent intent = new Intent();
        switch (v.getId()) {
            case R.id.top_100:
                gotoUtil.gotoAct(getActivity(), TopCreatorActivity.class, TopFragment.WRITER_TAG);
                break;
            case R.id.more_tv:
                intent.setClass(getActivity(), NewestWorkActivity.class);
                intent.putExtra(gotoUtil.INTENT_VALUE_ONE, TopFragment.WRITER_TAG);
                startActivity(intent);
                break;
            case R.id.daily_rank:
                gotoUtil.gotoAct(getActivity(), NovelTopWorkActivity.class, 2, "lastday");
                break;
            case R.id.week_rank:
                gotoUtil.gotoAct(getActivity(), NovelTopWorkActivity.class, 2, "week");
                break;
            case R.id.feed_rank:
                gotoUtil.gotoAct(getActivity(), NovelTopWorkActivity.class, 2, "pay");
                break;
        }
    }
}
